package com.store.satring.web;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.joda.time.format.DateTimeFormat;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.store.satring.dos.Customer;
import com.store.satring.dos.GLReport;
import com.store.satring.dos.GeneralLedger;
import com.store.satring.dos.Invoice;
import com.store.satring.utils.ReportUtils;
import com.store.satring.utils.StoreUtility;

@RequestMapping("/glreports")
@Controller
public class GLReportController {

	private final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
			"yyyy-MM-dd");

	@RequestMapping(method = RequestMethod.POST, produces = "text/html")
	public String create(@ModelAttribute("glReport") @Valid GLReport glReport,
			BindingResult bindingResult, Model uiModel,
			HttpServletRequest httpServletRequest, HttpServletResponse response) {
		try {
			List<Customer> customers = glReport.getCustomers() != null ? glReport
					.getCustomers() : new ArrayList<Customer>();
			StringBuilder customerIds = customers.size() > 0 ? new StringBuilder()
					: new StringBuilder("-1");
			for (Customer customer : customers) {
				customerIds.append(customer.getId() + ", ");
			}
			if (customerIds.toString().endsWith(", ")) {
				customerIds = new StringBuilder(customerIds.substring(0,
						customerIds.length() - 2));
			}

			List<Invoice> invoices = glReport.getInvoices() != null ? glReport
					.getInvoices() : new ArrayList<Invoice>();
			StringBuilder invoiceIds = invoices.size() > 0 ? new StringBuilder()
					: new StringBuilder("-1");
			for (Invoice invoice : invoices) {
				invoiceIds.append(invoice.getId() + ", ");
			}
			if (invoiceIds.toString().endsWith(", ")) {
				invoiceIds = new StringBuilder(invoiceIds.substring(0,
						invoiceIds.length() - 2));
			}

			List<GeneralLedger> generalLedgers = glReport.getGeneralLedgers() != null ? glReport
					.getGeneralLedgers() : new ArrayList<GeneralLedger>();
			StringBuilder generalLedgerIds = generalLedgers != null
					&& generalLedgers.size() > 0 ? new StringBuilder()
					: new StringBuilder("-1");
			for (GeneralLedger generalLedger : generalLedgers) {
				generalLedgerIds.append(generalLedger.getId() + ", ");
			}
			if (generalLedgerIds.toString().endsWith(", ")) {
				generalLedgerIds = new StringBuilder(
						generalLedgerIds.substring(0,
								generalLedgerIds.length() - 2));
			}

			Map<String, Object> parameters = new HashMap<String, Object>();
			parameters.put("GL_DATE_FROM",
					glReport.getGLDateFrom() == null ? null
							: getFormattedDate(glReport.getGLDateFrom()));
			parameters.put("GL_DATE_TO", glReport.getGLDateTo() == null ? null
					: getFormattedDate(glReport.getGLDateTo()));

			parameters.put("GL_IDS", generalLedgerIds.toString());
			parameters.put("INVOICE_IDS", invoiceIds.toString());
			parameters.put("CUSTOMER_IDS", customerIds.toString());
			parameters
					.put("SHOW_CLEAR_GL", glReport.getShowClearedGL() ? 1 : 0);
			parameters.put("SHOW_GL_DETAIL", glReport.getShowGLDetail());

			ReportUtils reportUtils = new ReportUtils("GLReport", parameters,
					response, httpServletRequest.getSession()
							.getServletContext());
			boolean isReportGenerated = reportUtils.executeReport();

			if (!isReportGenerated) {
				bindingResult.reject("no_data_found", "No Data Found");
			}

		} catch (Exception e) {
			String exceptionMessage = StoreUtility.getRouteCauseMessage(e);
			bindingResult.reject("error_occured", "Exception Message : "
					+ exceptionMessage);

		}
		if (bindingResult.hasErrors()) {
			populateEditForm(uiModel, glReport);
			return "glreports/create";
		}

		uiModel.asMap().clear();

		return null;
	}

	private String getFormattedDate(Date date) {
		String formatedDate = DATE_FORMAT.format(date);
		return formatedDate;
	}

	@RequestMapping(params = "form", produces = "text/html")
	public String createForm(Model uiModel) {
		populateEditForm(uiModel, new GLReport());
		return "glreports/create";
	}

	void addDateTimeFormatPatterns(Model uiModel) {
		uiModel.addAttribute(
				"GLReport__gldatefrom_date_format",
				DateTimeFormat.patternForStyle("M-",
						LocaleContextHolder.getLocale()));
		uiModel.addAttribute(
				"GLReport__gldateto_date_format",
				DateTimeFormat.patternForStyle("M-",
						LocaleContextHolder.getLocale()));
	}

	void populateEditForm(Model uiModel, GLReport gLReport) {

		List<Customer> allCustomers = Customer.findAllCustomers();
		List<GeneralLedger> allGeneralLedgers = GeneralLedger
				.findAllGeneralLedgers();
		List<Invoice> allInvoices = Invoice.findAllInvoices();

		// gLReport.setCustomers(allCustomers);
		// gLReport.setGeneralLedgers(allGeneralLedgers);
		// gLReport.setInvoices(allInvoices);

		uiModel.addAttribute("glReport", gLReport);
		addDateTimeFormatPatterns(uiModel);
		uiModel.addAttribute("customers", allCustomers);
		uiModel.addAttribute("generalledgers", allGeneralLedgers);
		uiModel.addAttribute("invoices", allInvoices);

	}

}
